import sys

def ReadConfigFile():
    try:
        config = open(sys.argv[1] + "config","r")
    except IOError:
        print "There is no config file in directory", sys.argv[1]
	sys.exit()

    """  open config file, read feature types and
         performance data file
    """
    featureFiles = []
    while True:
        parts = config.readline().split()    
	if len(parts) == 0:
	    break
	if parts[0] in ["idiom", "graphlet", "ngram", "libcall", "data", "addressing"] :
	    try:
	        featureFiles.append(open(sys.argv[1] + parts[2],"r"))
	    except IOError:
	        print "Cannot find file", sys.argv[1] + parts[2], "for", parts[0], "features"
	
	if parts[0] == "performance":
	    try:
	        targetFile = open(sys.argv[1] + parts[1], "r")
	    except IOError:
	        print "Cannot find performance data file", sys.argv[1] + parts[1]
		sys.exit()

    config.close()
    return featureFiles, targetFile

def ReadTargetFile(targetFile):
    targets = {}
    for line in targetFile.read().split("\n")[:-1]:
        parts = line.split(",")
	parts[-1] = parts[-1][:-1]
	targets[parts[0]] = parts[1:]
    targetFile.close()
    return targets

def IndexFeatures(featureFiles, targets):
    featureIndex = {}
    
    instanceSet = {}
    totalFeature = 0
    
    
    """  all feature files share the same order of instance,
         read a line from each file and combine it into a complete
	 instance, index all features.
    """
    
    over = False
    while not over:         
        instance = []
	for f in featureFiles:  
	    instanceString = f.readline()
	    if instanceString == "":
	        over = True
		break
            instanceList = instanceString.split()
	    debug = {}
	    id  = instanceList[0]
	    if id not in targets:
	        continue

	    for featurePair in instanceList[1:]:
	        feature,count = featurePair.split(":")
		count = int(count)
		if not feature in featureIndex:
		    totalFeature += 1
		    featureIndex[feature] = totalFeature
		instance.append((featureIndex[feature], count))	

		# Each feature should only appear once in each data instance
	        if feature in debug:
		    print "Duplicate:", feature
	        else:
	            debug[feature] = True
        if over:
            break
	instanceSet[id] = instance

    for f in featureFiles:
        f.close()

    return instanceSet

def OutputDataInstances(targets, instanceSet):

    numberOfCounters = len(targets[targets.keys()[0]])
    for i in range(numberOfCounters):
	f = open(sys.argv[2] + "_" + str(i), "w")
	for id in targets:
	    if targets[id][i] == "--" or float(targets[id][i]) == 0:
	        continue

	    if id not in instanceSet:
	        print id ,"appears in performance data but not in code feature data"
		continue
	    instanceSet[id].sort()

	    f.write("{0}".format(targets[id][i]))
	    for index, count in instanceSet[id]:
	        f.write(" {0}:{1}".format(index, count))	  
	    f.write("\n")
        f.close()    

if len(sys.argv) < 3:
    print "Usage: python integrate.py <working directory> <output prefix>"
    sys.exit()

if not sys.argv[1][-1] == '/':
    sys.argv[1] += '/'

sys.argv[2] = sys.argv[1] + sys.argv[2]

featureFiles, targetFile = ReadConfigFile()

# targets is a dictionary mapping a loop name to a list of counter values
targets = ReadTargetFile(targetFile)

# instanceSet is a dictionary mapping a loop name to a list of code features
instanceSet = IndexFeatures(featureFiles, targets)

# Merge the performance and code feature data
OutputDataInstances(targets, instanceSet)


        
